package PLCSymbolAndScope.PLCSymbolTables;


import PLCSymbolAndScope.IDGenerator;
import PLCSymbolAndScope.PLCScope.PLCScope;
import PLCSymbolAndScope.PLCScopeStack;
import PLCSymbolAndScope.PLCSymbols.PLCISTypeDeclType;
import PLCSymbolAndScope.PLCSymbols.PLCSymbol;
import PLCSymbolAndScope.PLCSymbols.PLCTypeDeclSymbol;

import java.util.HashMap;

//总符号表（依靠ID索引）
public final class PLCTotalSymbolTable {

    //TODO:考虑优化
    //用户定义的类型注册表
    static public HashMap<Integer, HashMap<String, PLCSymbol>> userDefinitionType = new HashMap<>();

    //所有类型表（按序号索引类型名称）
    static public HashMap<Integer, String> typeNameMap = new HashMap<>();

    //所有类型表（根据名称索引类型序号）
    static public HashMap<String, Integer> typeNumMap = new HashMap<>();

    //按唯一ID索引出现的所有符号
    static public HashMap<Integer, PLCSymbol> totalSymbolMap = new HashMap<>();

    //按唯一ID索引所有的作用域表
    static public HashMap<Integer, PLCScope> totalScopeMap = new HashMap<>();

    //按唯一ID索引的所有子符号表
    static public HashMap<Integer, PLCSymbolTable> totalTableMap = new HashMap<>();

    //将符号加入总表
    static public void addSymbol(PLCSymbol symbol){
        totalSymbolMap.put(symbol.getSymbolId(), symbol);
    }

    //添加作用域
    static public void addScope(PLCScope scope){
        totalScopeMap.put(scope.getScopeID(), scope);
    }

    //添加表
    static public void addTable(PLCSymbolTable table){
        totalTableMap.put(table.getTableId(), table);
    }

    //集合添加一个作用域、符号、表
    static public void addMember(PLCISTypeDeclType symbol){
        addSymbol(symbol);
        addScope(symbol.getImportScope());
        addTable(symbol.getImportSymbolTable());
    }

    //添加一个声明的类型以及其符号
    static public void addType(PLCTypeDeclSymbol declSymbol){
        addSymbol(declSymbol);
        typeNameMap.put(declSymbol.getTypeId(), declSymbol.name);
        typeNumMap.put(declSymbol.name, declSymbol.getTypeId());
    }

    //添加基本类型的类型id
    static public void totalTableInit(){
        PLCTypeDeclSymbol sInt = new PLCTypeDeclSymbol(IDGenerator.SINTID, IDGenerator.SINTID, "SINT");
        addType(sInt);
        //TODO:待添加基本类型

    }

    //查找类型
    static public Integer findTypeByName(String name){
        return typeNumMap.get(name);
    }
}
